/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package it.polimi.deib.se2.meteocal.gui;


import it.polimi.deib.se2.meteocal.business.boundary.EventManager;
import it.polimi.deib.se2.meteocal.business.boundary.InvitationManager;
import it.polimi.deib.se2.meteocal.business.control.WeatherCodeConverter;
import it.polimi.deib.se2.meteocal.business.entity.Event;
import it.polimi.deib.se2.meteocal.business.entity.Invitation;
import it.polimi.deib.se2.meteocal.business.entity.Location;
import it.polimi.deib.se2.meteocal.business.entity.User;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;

import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.inject.Named;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.DefaultScheduleModel;
import org.primefaces.model.ScheduleModel;

/**
 *
 * @author valerioarcerito
 */
@Named
@SessionScoped
public class OthersCalendarBean implements Serializable{
    

    @EJB
    private EventManager em;
    @EJB
    private InvitationManager im;
    
    private ScheduleModel eventModel;
    private User user;
    
    private int badWeatherLevel;
    private Date startDate;
    private Date endDate;
    private boolean isPublic;
    private boolean outdoor;
    private String title;
    private String locationName;
    private Location location;
    private long id;
    private String invitees;
    private String weather;
    private String iconURL;
    @Inject 
    private FindUserBean fub;
    
    private MeteoCalScheduleEvent scheduleEvent = new MeteoCalScheduleEvent();

    
    
    public OthersCalendarBean() {
    }
    
    @PostConstruct
    public void init() {
        eventModel = new DefaultScheduleModel();
        this.user= getFub().getUser();
        List<Event> eventCollection = (List<Event>) getFub().getUser().getCalendar().getEventCollection();
        
        for (Event i : eventCollection) {
            if(i.getIsPublic()==true){
                eventModel.addEvent(new MeteoCalScheduleEvent(i.getId(), i.getTitle(), i.getStartDate(), i.getEndDate()));
            }else if(i.getIsPublic()==false){
                eventModel.addEvent(new MeteoCalScheduleEvent(i.getId(), "", i.getStartDate(), i.getEndDate()));
            }      
        }
    }
    
    
    public void setUser(User user){
        this.user = user;
    }
    
    public User getUser(){
        return user;
    }
    
   
    /**
     * @return the eventModel
     */
    public ScheduleModel getEventModel() {
        return eventModel;
    }

    /**
     * @param eventModel the eventModel to set
     */
    public void setEventModel(ScheduleModel eventModel) {
        this.eventModel = eventModel;
    }

    /**
     * @return the badWeatherLevel
     */
    public int getBadWeatherLevel() {
        return badWeatherLevel;
    }

    /**
     * @param badWeatherLevel the badWeatherLevel to set
     */
    public void setBadWeatherLevel(int badWeatherLevel) {
        this.badWeatherLevel = badWeatherLevel;
    }

    /**
     * @return the startDate
     */
    public Date getStartDate() {
        return startDate;
    }

    /**
     * @param startDate the startDate to set
     */
    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }

    /**
     * @return the endDate
     */
    public Date getEndDate() {
        return endDate;
    }

    /**
     * @param endDate the endDate to set
     */
    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }

    /**
     * @return the isPublic
     */
    public boolean isIsPublic() {
        return isPublic;
    }

    /**
     * @param isPublic the isPublic to set
     */
    public void setIsPublic(boolean isPublic) {
        this.isPublic = isPublic;
    }

    /**
     * @return the outdoor
     */
    public boolean isOutdoor() {
        return outdoor;
    }

    /**
     * @param outdoor the outdoor to set
     */
    public void setOutdoor(boolean outdoor) {
        this.outdoor = outdoor;
    }

    /**
     * @return the title
     */
    public String getTitle() {
        return title;
    }

    /**
     * @param title the title to set
     */
    public void setTitle(String title) {
        this.title = title;
    }

    /**
     * @return the locationName
     */
    public String getLocationName() {
        return locationName;
    }

    /**
     * @param locationName the locationName to set
     */
    public void setLocationName(String locationName) {
        this.locationName = locationName;
    }

    /**
     * @return the location
     */
    public Location getLocation() {
        return location;
    }

    /**
     * @param location the location to set
     */
    public void setLocation(Location location) {
        this.location = location;
    }

    /**
     * @return the id
     */
    public long getId() {
        return id;
    }

    /**
     * @param id the id to set
     */
    public void setId(long id) {
        this.id = id;
    }
    
    public void onEventSelect(SelectEvent selectEvent) {
        
        scheduleEvent = (MeteoCalScheduleEvent) selectEvent.getObject();
        setId(scheduleEvent.getIdEvent());
        Event findEvent=em.find(scheduleEvent.getIdEvent());
        if(findEvent.isIsPublic()==true){
            //precompiled field
            setTitle(scheduleEvent.getTitle());
            setStartDate(scheduleEvent.getStartDate());
            setEndDate(scheduleEvent.getEndDate());

            //Event findEvent=em.find(scheduleEvent.getIdEvent());

            setOutdoor(findEvent.isOutdoor());
            setIsPublic(findEvent.getIsPublic());
            setBadWeatherLevel(findEvent.getBadWeatherLevel());

            Location loc = findEvent.getIdLocation();
            setLocation(loc); 
            setLocationName(loc.getLocName());
            
            List<Invitation> invitationList = im.getInvitations(findEvent);
            StringBuilder inv = new StringBuilder();
        
            for(Invitation i : invitationList){
              inv.append(i.getUserInvited().getEmail());
              if(i != invitationList.get(invitationList.size()-1)){
                 inv.append(",");
                }
            }
            setInvitees(inv.toString());
            
            String weath = catchWeather(findEvent);
            setWeather(weath);
            
            String icon = WeatherCodeConverter.getIcon(weath);
            setIconURL(icon);
        }else{
            setStartDate(scheduleEvent.getStartDate());
            setEndDate(scheduleEvent.getEndDate());
            //clean field
            setTitle("");
            setOutdoor(false);
            setIsPublic(false);
            setBadWeatherLevel(0);
            setLocationName("");
            setLocation(null);
            setInvitees("");
            setWeather("");
            setIconURL(WeatherCodeConverter.getIcon("0")); // set default icon (meteocal)
           
        }
            
        
    }

    /**
     * @return the em
     */
    public EventManager getEm() {
        return em;
    }

    /**
     * @param em the em to set
     */
    public void setEm(EventManager em) {
        this.em = em;
    }

    /**
     * @return the fub
     */
    public FindUserBean getFub() {
        return fub;
    }

    /**
     * @param fub the fub to set
     */
    public void setFub(FindUserBean fub) {
        this.fub = fub;
    }

    /**
     * @return the scheduleEvent
     */
    public MeteoCalScheduleEvent getScheduleEvent() {
        return scheduleEvent;
    }

    /**
     * @param scheduleEvent the scheduleEvent to set
     */
    public void setScheduleEvent(MeteoCalScheduleEvent scheduleEvent) {
        this.scheduleEvent = scheduleEvent;
    }
    
    public void resetCalendar(){
        eventModel.clear();
    }
    
    public void insertCalendar(){
        this.user= getFub().getUser();
        List<Event> eventCollection = (List<Event>) getFub().getUser().getCalendar().getEventCollection();
        for (Event i : eventCollection) {
            if(i.getIsPublic()==true){
                eventModel.addEvent(new MeteoCalScheduleEvent(i.getId(), i.getTitle(), i.getStartDate(), i.getEndDate()));
            }else if(i.getIsPublic()==false){
                eventModel.addEvent(new MeteoCalScheduleEvent(i.getId(), "", i.getStartDate(), i.getEndDate()));
            }
        }
    } 
    
    public String getInvitees(){
        return invitees;
    }
    
    public void setInvitees(String invitees){
        this.invitees = invitees;
    }
    
    public String getWeather(){
        return weather;
    }
    
    public void setWeather(String weather){
        this.weather = weather;
    }
    // da eliminare 
    private String catchWeather(Event event) {
        int days = (int) getDateDiff(startDate, TimeUnit.DAYS);
        String weatherExtracted = new String();
        if(days<0)
            weatherExtracted = "Day in the past";
        if(days>15)
            weatherExtracted = "Weather data not yet available";
        if(days>=0 && days<=15){
            Location eventLocation = event.getIdLocation();
            String weatherString = eventLocation.getWeather();
            weatherExtracted = extractWeather(weatherString, days);
        }
        
        return weatherExtracted;
    }
    private int getDateDiff(Date startdate, TimeUnit timeUnit) {
        Date now = new Date();
        now.setHours(00);
        now.setMinutes(00);
        now.setSeconds(00);
        long diffInMillies = startdate.getTime() - now.getTime();
        return (int)timeUnit.convert(diffInMillies,TimeUnit.MILLISECONDS);
    }
    private String extractWeather(String weatherString, int days) {
        String[] weathers = weatherString.split(",");
        return weathers[days];
    }
    
    public String getIconURL(){
        return iconURL;
    }
    
    public void setIconURL(String iconURL){
        this.iconURL = iconURL;
    }
}
